package com.itxiuyixiu.volunteer.service;

import com.itxiuyixiu.entity.enums.AccountState;
import com.itxiuyixiu.entity.enums.AuthorityType;
import com.itxiuyixiu.entity.mapper.AdminReaderMapper;
import com.itxiuyixiu.entity.mapper.AdminWriterMapper;
import com.itxiuyixiu.entity.model.Admin;
import com.itxiuyixiu.tools.security.user.GetUser;
import com.itxiuyixiu.volunteer.common.errors.ServiceException;
import com.itxiuyixiu.volunteer.dto.AdminForgetPasswordParam;
import com.itxiuyixiu.volunteer.dto.AdminModifyMessageParam;
import com.itxiuyixiu.volunteer.dto.AdminRegisterParam;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;

/**
 * @author 黄磊
 * @date 2020/5/1
 */
@Slf4j
@Service
public class AdminCommonService {
    @Resource
    private AdminWriterMapper adminWriterMapper;
    @Resource
    private AdminReaderMapper adminReaderMapper;
    @Autowired
    private PasswordEncoder passwordEncoder;
    @Autowired
    private VerificationService verificationService;

    public Integer saveAdmin(AdminRegisterParam adminDto) {
        if (isEmailUsed(adminDto.getAdminEmail())) {
            throw new ServiceException("邮箱已被他人使用");
        }
        if (!verificationService.checkVerification(adminDto.getAdminEmail(), adminDto.getVerification())) {
            throw new ServiceException("邮箱验证码错误");
        }
        Boolean flag = adminReaderMapper.existByUsername(adminDto.getUsername());
        if (flag) {
            throw new ServiceException("用户名已被注册");
        }
        Admin admin = new Admin();
        admin.setUsername(adminDto.getUsername());
        admin.setPassword(passwordEncoder.encode(adminDto.getPassword()));
        if (adminDto.getAuthorities().contains(AuthorityType.ROLE_ADMIN)) {
            throw new ServiceException("禁止注册网站运营者管理员");
        }
        admin.setAuthorities(adminDto.getAuthorities());
        admin.addAuthority(AuthorityType.BASIC_ADMIN_AUTHORITY);
        admin.setAdminEmail(adminDto.getAdminEmail());
        admin.setAccountState(AccountState.AUDITING);
        adminWriterMapper.saveAdmin(admin);
        log.info("成功创建管理员：" + admin.getUsername());
        return admin.getAdminId();
    }

    public Admin findAdmin() {
        return adminReaderMapper.findAdminByUsername(GetUser.getUserName()).orElseThrow(() -> new ServiceException("用户信息不存在"));
    }

    public void modifyAdmin(AdminModifyMessageParam adminDto) {
        Admin admin = findAdmin();
        admin.setNickName(adminDto.getNickName());
        admin.setAdminEmail(adminDto.getAdminEmail());
        admin.setHeadImage(adminDto.getHeadImage());
        adminWriterMapper.modifyAdminById(admin);
        log.info("管理员" + admin.getUsername() + "成功修改自己管理员信息");
    }

    public void modifyPassword(String oldPassword, String newPassword) {
        Admin admin = findAdmin();
        if (!passwordEncoder.matches(oldPassword, admin.getPassword())) {
            throw new ServiceException("新旧密码不一致");
        }
        admin.setPassword(passwordEncoder.encode(newPassword));
        adminWriterMapper.modifyAdminById(admin);
        log.info("管理员" + admin.getUsername() + "成功修改自己密码");
    }

    /**
     * 管理员的忘记密码
     *
     * @param dto 信息
     */
    public void forgetPassword(AdminForgetPasswordParam dto) {
        if (!verificationService.checkVerification(dto.getAdminEmail(), dto.getVerification())) {
            throw new ServiceException("验证码错误");
        }
        Admin admin = findAdmin();
        if (!admin.getAdminEmail().equals(dto.getAdminEmail())) {
            throw new ServiceException("邮箱不符");
        }
        admin.setPassword(passwordEncoder.encode(dto.getPassword()));
        adminWriterMapper.modifyAdminById(admin);
        log.info("管理员" + admin.getUsername() + "成功重置自己密码");
    }

    /**
     * 查看邮箱是否被使用
     *
     * @param email 邮箱
     * @return true—邮箱已被使用，false—邮箱未被使用
     */
    public boolean isEmailUsed(String email) {
        return adminReaderMapper.existByEmail(email);
    }
}
